
#include "openGLwindow.h"

#include <QString>
#include <QMessageBox>


OpenGLWindow::OpenGLWindow(QWidget *parent) : QGLWidget(QGLFormat(QGL::SampleBuffers), parent)
{
  glError = GL_NO_ERROR;
}

OpenGLWindow::~OpenGLWindow()
{
}

void OpenGLWindow::initializeGL()
{
  int vmaj = format().majorVersion();
  int vmin = format().minorVersion();
  if( vmaj < 2 ){
    QMessageBox::warning(this, tr("Wrong OpenGL version"), tr("OpenGL version 2.0 or higher needed. You have %1.%2, so some functions may not work properly.").arg(vmaj).arg(vmin));
  }
  qDebug() << tr("OpenGL Version: %1.%2").arg(vmaj).arg(vmin);

  pbo->initCuda();

  QObject::connect(pbo, SIGNAL(bufferChanged()), this, SLOT(update()));

  glClearColor(0, 0, 0, 1);
  glDisable(GL_DEPTH_TEST);
  glShadeModel(GL_FLAT);
  glDisable(GL_LIGHTING);
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity(); 
}

void OpenGLWindow::resizeGL(int w, int h)
{
	glViewport(0, 0, pbo->width, pbo->height);
}

void OpenGLWindow::paintGL(){
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  glMatrixMode(GL_MODELVIEW); //Select The Modelview Matrix
  glLoadIdentity();

  glEnable(GL_TEXTURE_2D);
  // run CUDA kernel
  
  // now bind buffer after cuda is done
  pbo->bind();

  // Draw a single Quad with texture coordinates for each vertex.
  glBegin(GL_QUADS);
    glTexCoord2f(0.0f,1.0f);  glVertex3f(-1.0f,-1.0f,-1.0f);
    glTexCoord2f(0.0f,0.0f);  glVertex3f(-1.0f,1.0f,-1.0f);
    glTexCoord2f(1.0f,0.0f);  glVertex3f(1.0f,1.0f,-1.0f);
    glTexCoord2f(1.0f,1.0f);  glVertex3f(1.0f,-1.0f,-1.0f);
  glEnd();

  pbo->release();

  glColor3f(0,1,0);

  static int iter = 0;
  QString str;
  str.setNum(iter++);
  str.prepend(tr("Rysowano: "));
  renderText(10,10, QString(str));

  glColor3f(1,1,1);
  
  glError = glGetError();
}

//-----------------------------------------------------------------------------
// update - SLOT Timer tiupdate
//-----------------------------------------------------------------------------
void OpenGLWindow::update(){
  if( glError != GL_NO_ERROR ){ // OpenGL ocurre
    
    QMessageBox::warning(this, "OpenGL Error: "+QString::number(glError), getGLError());
    glError=GL_NO_ERROR;
  }else{
    updateGL();
  }
}

QString OpenGLWindow::getGLError(){
  QString exception = "No error";
  switch (glError)
  {
    // see macro on top
    GLERROR(GL_INVALID_ENUM)
    GLERROR(GL_INVALID_VALUE)
    GLERROR(GL_INVALID_OPERATION)
    GLERROR(GL_STACK_OVERFLOW)
    GLERROR(GL_STACK_UNDERFLOW)
    GLERROR(GL_OUT_OF_MEMORY)
#ifdef GL_INVALID_INDEX
    GLERROR(GL_INVALID_INDEX)
#endif
#ifdef GL_INVALID_FRAMEBUFFER_OPERATION_EXT
    GLERROR(GL_INVALID_FRAMEBUFFER_OPERATION_EXT)
#endif
    default:
      exception.sprintf("Unknown GL error: %04x\n", glError);
      break;
  }
  return exception;
}